package com.yiren.manager.ctrl.cost;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.yiren.core.exception.MyException;
import com.yiren.core.exception.SwallowException;
import com.yiren.core.repository.utils.QueryResult;
import com.yiren.core.utils.FavoriteSet;
import com.yiren.core.utils.HTTPResult;
import com.yiren.core.utils.JsonMapperTool;
import com.yiren.core.utils.MyMessage;
import com.yiren.core.utils.UUIDGenerator;
import com.yiren.entity.YrBeHospitalPledge;
import com.yiren.entity.YrElder;
import com.yiren.entity.YrElderArrearage;
import com.yiren.entity.YrElderBeHospital;
import com.yiren.entity.YrElderOutOrder;
import com.yiren.entity.YrElderPayRecord;
import com.yiren.entity.YrElderWallet;
import com.yiren.entity.YrElderWalletRechargeRecord;
import com.yiren.entity.YrMealCard;
import com.yiren.entity.YrOutFeeRecord;
import com.yiren.entity.YrPaper;
import com.yiren.entity.YrPaperRecord;
import com.yiren.entity.YrRoomAssetComp;
import com.yiren.manager.ctrl.elder.YrElderBaseController;
import com.yiren.manager.form.base.CommParamForm;
import com.yiren.manager.form.cost.YrArrearageDescForm;
import com.yiren.manager.form.cost.YrElderCompDescForm;
import com.yiren.manager.form.cost.YrElderOutCostForm;
import com.yiren.manager.service.iface.assets.YrRoomAssetCompService;
import com.yiren.manager.service.iface.cost.YrElderArrearageService;
import com.yiren.manager.service.iface.cost.YrElderPayRecordService;
import com.yiren.manager.service.iface.cost.YrElderWalletRechargeRecordService;
import com.yiren.manager.service.iface.cost.YrPaperService;
import com.yiren.manager.service.iface.elder.YrElderBeHospitalService;
import com.yiren.manager.service.iface.elder.YrElderOutOrderService;
import com.yiren.manager.service.iface.elder.YrElderService;
import com.yiren.manager.service.iface.elder.YrElderWalletService;
import com.yiren.manager.service.iface.lease.YrBeHospitalPledgeService;
import com.yiren.manager.service.iface.messhall.YrMealCardService;

/**
 * 出院费用结清控制类
 * @author Administrator
 *
 */
@RequestMapping("elderOutCost")
@Controller
public class YrElderOutCostController extends YrElderBaseController<Object, Object>{
	
	@Autowired
	private YrBeHospitalPledgeService beHospitalPledgeService;
	
	@Autowired
	private YrElderWalletService elderWalletService;
	
	@Autowired
	private YrMealCardService mealCardService;
	
	@Autowired
	private YrRoomAssetCompService roomAssetCompService;
	
	@Autowired
	private YrElderArrearageService elderArrearageService;
	
	@Autowired
	private YrElderService elderService;
	
	@Autowired
	private YrElderBeHospitalService elderBeHospitalService;
	
	@Autowired
	private YrElderOutOrderService elderOutOrderService;

	@Autowired
	private YrElderPayRecordService elderPayRecordService;
	
	@Autowired
	private YrElderWalletRechargeRecordService elderWalletRechargeRecordService;

	@Autowired
	private YrPaperService paperService;
	
	@RequestMapping("findElderOutCost")
	@ResponseBody
	public HTTPResult<YrElderOutCostForm> findElderOutCost(String beHospitalId) throws MyException{
		HTTPResult<YrElderOutCostForm> result = new HTTPResult<YrElderOutCostForm>();
		
		YrElderBeHospital elderBeHospital = elderBeHospitalService.findOne(beHospitalId);
		if(null==elderBeHospital){
			throwExp("查询相关入院登记信息");
		}
		YrElder elder = elderService.findOne(elderBeHospital.getElderId());
		YrElderOutCostForm form = new YrElderOutCostForm();
		String sqlWhere = "be_hospital_id=?1 AND STATUS=0";
		Float pledge = Float.valueOf(0);
		QueryResult<YrBeHospitalPledge> qrBeHospitalPledge = beHospitalPledgeService.find(YrBeHospitalPledge.class, sqlWhere, new Object[]{beHospitalId});
		for(YrBeHospitalPledge beHospitalPledge : qrBeHospitalPledge.getResultList()){
			if(beHospitalPledge.getPledge()!=null){
				pledge=pledge+beHospitalPledge.getPledge();
			}
		}
//		QueryResult<YrLeasePledge> qrLeasePledge = leasePledgeService.find(YrLeasePledge.class, sqlWhere, new Object[]{elder.getElderId()});
//		for(YrLeasePledge leasePledge : qrLeasePledge.getResultList()){
//			if(leasePledge.getPledge()!=null){
//				pledge=pledge+leasePledge.getPledge();
//			}
//		}
		form.setPledge(pledge);
		sqlWhere = "elder_card_id=?1";
		QueryResult<YrElderWallet> qrElderWallet = elderWalletService.find(YrElderWallet.class,sqlWhere, new Object[]{elder.getCardId()});
		if(qrElderWallet.getTotalRecord()>0){
			YrElderWallet elderWallet = qrElderWallet.getResultList().get(0);
			form.setWalletBalance(elderWallet.getWalletBalance());
		}
		sqlWhere = "card_card_id=?1";
		QueryResult<YrMealCard> qrMealCard = mealCardService.find(YrMealCard.class, sqlWhere, new Object[]{elder.getCardId()});
		if(qrMealCard.getTotalRecord()>0){
			YrMealCard mealCard = qrMealCard.getResultList().get(0);
			form.setMealCardBalance(mealCard.getBalance());
		}
		sqlWhere = "be_hospital_id=?1 AND status=0";
		QueryResult<YrElderArrearage> qrElderArrearage = elderArrearageService.find(YrElderArrearage.class,sqlWhere,new Object[]{beHospitalId});
		Map<String, YrArrearageDescForm> arrMap = new HashMap<String, YrArrearageDescForm>();
		for(YrElderArrearage elderArrearage : qrElderArrearage.getResultList()){
			YrArrearageDescForm arrearageDescForm = null;
			if(arrMap.containsKey(elderArrearage.getArrearageDesc())&&
					arrMap.get(elderArrearage.getArrearageDesc()).getArrearageMoney()-elderArrearage.getArrearageMoney()==0&&
					arrMap.get(elderArrearage.getArrearageDesc()).getArrearageType()==elderArrearage.getArrearageType()){
				arrearageDescForm = arrMap.get(elderArrearage.getArrearageDesc());
				arrearageDescForm.setQuantity(arrearageDescForm.getQuantity()+1);
				arrMap.put(elderArrearage.getArrearageDesc(), arrearageDescForm);
			}else{
				arrearageDescForm = new YrArrearageDescForm();
				arrearageDescForm.setArrearageDesc(elderArrearage.getArrearageDesc());
				arrearageDescForm.setQuantity(1);
				arrearageDescForm.setArrearageMoney(elderArrearage.getArrearageMoney());
				arrearageDescForm.setArrearageType(elderArrearage.getArrearageType());
			}
		}
		List<YrArrearageDescForm> arrearageDescForms = new ArrayList<YrArrearageDescForm>();
		for(Map.Entry<String, YrArrearageDescForm> entry : arrMap.entrySet()){
			arrearageDescForms.add(entry.getValue());
		}
		form.setArrearageDescForms(arrearageDescForms);
		sqlWhere="be_hospital_id=?1 AND comp_status=0";
		QueryResult<YrRoomAssetComp> qrRoomAssetComp = roomAssetCompService.find(YrRoomAssetComp.class, sqlWhere, new Object[]{beHospitalId});
		
		Map<String, YrElderCompDescForm> compMap = new HashMap<String, YrElderCompDescForm>();
		for(YrRoomAssetComp roomAssetComp : qrRoomAssetComp.getResultList()){
			YrElderCompDescForm elderCompDescForm = null;
			if(compMap.containsKey(roomAssetComp.getRoomAssetId())&&
					compMap.get(roomAssetComp.getRoomAssetId()).getAssetName().equals(roomAssetComp.getAssetName())){
				elderCompDescForm = compMap.get(roomAssetComp.getRoomAssetId());
				elderCompDescForm.setCompQuantity(elderCompDescForm.getCompQuantity()+1);
				compMap.put(roomAssetComp.getAssetId(), elderCompDescForm);
			}else{
				elderCompDescForm = new YrElderCompDescForm();
				elderCompDescForm.setAssetName(roomAssetComp.getAssetName());
				elderCompDescForm.setCompQuantity(1);
				elderCompDescForm.setPrice(roomAssetComp.getPrice());
			}
		}
		List<YrElderCompDescForm> elderCompDescForms = new ArrayList<YrElderCompDescForm>();
		for(Map.Entry<String, YrElderCompDescForm> entry : compMap.entrySet()){
			elderCompDescForms.add(entry.getValue());
		}
		form.setElderCompDescForms(elderCompDescForms);
			
		List<YrElderOutCostForm> formList = new ArrayList<YrElderOutCostForm>();
		formList.add(form);
		result.setData(formList);
		
		return result;
	}
	
	/**
	 * 出院费用结清
	 * @param elderId
	 * @return
	 * @throws MyException 
	 * @throws SwallowException 
	 */
	@RequestMapping("costSettlement")
	@ResponseBody
	public HTTPResult<YrElderOutCostForm> costSettlement(String beHospitalId,String commParamForm) throws MyException, SwallowException{
		HTTPResult<YrElderOutCostForm> result = new HTTPResult<YrElderOutCostForm>();
		JsonMapperTool tool = new JsonMapperTool(commParamForm);
		CommParamForm loginedUser = tool.mapper("loginedUser", CommParamForm.class);
		if(null==beHospitalId){
			throwExp("参数有误");
		}
		YrElderBeHospital elderBeHospital = elderBeHospitalService.findOne(beHospitalId);
		if(elderBeHospital==null){
			throwExp("查询不到该老者相关住院信息");
		}
		if(elderBeHospital.getBeStatus()==2){//如果已经出院
			throwExp("该老者已经出院，无需结清");
		}
		if(null==elderBeHospital){
			throwExp("查询不到该老者的相关入院登记信息");
		}
		YrElder elder = elderService.findOne(elderBeHospital.getElderId());
		if(null==elder){
			throwExp("查询不到相关老者信息");
		}
//		elderBeHospital.setBeStatus(2);//设置为出院状态
//		elderBeHospital.setBeType(2);//床位状态：0正在住1保留2已出院
//		elderBeHospital.setOutDate(new Date());//设置出院时间
		
//		//床位设置为空闲状态
//		YrBed bed = bedService.findOne(elderBeHospital.getBedId());
//		if(null!=bed){
//			bed.setUpdateTime(new Date());
//			bed.setUseStatus(0);
//		}
		
		YrOutFeeRecord outFeeRecord = new YrOutFeeRecord();
		outFeeRecord.setOuFeeRecordId(UUIDGenerator.getUUID());
		outFeeRecord.setBeHospitalId(beHospitalId);
		outFeeRecord.setCreateTime(new Date());
		outFeeRecord.setCreateId("-1");
		
		Float pledge = 0F;
		//退回所有押金
		String sqlWhere = "be_hospital_id=?1";
		List<YrBeHospitalPledge> beHospitalPledges = new ArrayList<YrBeHospitalPledge>();
		QueryResult<YrBeHospitalPledge> qrBeHospitalPledge = beHospitalPledgeService.find(YrBeHospitalPledge.class, sqlWhere, new Object[]{beHospitalId});
		for(YrBeHospitalPledge entity : qrBeHospitalPledge.getResultList()){
			entity.setStatus(1);
			entity.setReturnTime(new Date());
			pledge=pledge+entity.getPledge();
			beHospitalPledges.add(entity);
		}
		outFeeRecord.setPledge(pledge);
//		QueryResult<YrLeasePledge> YrLeasePledge = leasePledgeService.find(YrLeasePledge.class, sqlWhere, new Object[]{elder.getElderId()});
//		for(YrLeasePledge entity : YrLeasePledge.getResultList()){
//			entity.setStatus(1);
//			entity.setReturnTime(new Date());
//			leasePledges.add(entity);
//		}
		
		// 查询出所有的预交款
		QueryResult<YrElderWalletRechargeRecord> reQueryResult = null;
		// if (endTime == null){//如果正在住院
		sqlWhere = "elder_id=?1 AND be_hospital_id=?2";
		reQueryResult = elderWalletRechargeRecordService.find(YrElderWalletRechargeRecord.class, sqlWhere,
				new Object[] { elder.getElderId(), beHospitalId });

		Float prePay = 0F;
		for (YrElderWalletRechargeRecord rechargeRecord : reQueryResult.getResultList()) {
			prePay += rechargeRecord.getRechargeMoney();
		}
		
		outFeeRecord.setTotalPay(prePay);
		QueryResult<YrElderPayRecord> qrElderPayRecord = null;
		// 查询出所有的费用
		sqlWhere = "elder_id=?1 AND be_hospital_id=?2 AND pay_way<>3";
		qrElderPayRecord = elderPayRecordService.find(YrElderPayRecord.class, sqlWhere,
				new Object[] { elder.getElderId(), beHospitalId });

		Float totalFee = 0F;
		for (YrElderPayRecord elderPayRecord : qrElderPayRecord.getResultList()) {
			totalFee += elderPayRecord.getPayMoney();
		}
		outFeeRecord.setTotalFee(totalFee);
		//清空钱包
		sqlWhere = "elder_id=?1";
		YrElderWallet elderWallet = null;
		QueryResult<YrElderWallet> qrElderWallet = elderWalletService.find(YrElderWallet.class, sqlWhere, new Object[]{elder.getElderId()});
		if(qrElderWallet.getTotalRecord()>0){
			elderWallet = qrElderWallet.getResultList().get(0);
			outFeeRecord.setMoneyWallet(elderWallet.getWalletBalance());
			elderWallet.setWalletBalance(Float.valueOf(0));
		}
		//清空饭卡
		sqlWhere = "card_card_id=?1";
		YrMealCard mealCard = null;
		QueryResult<YrMealCard> qrMealCard = mealCardService.find(YrMealCard.class, sqlWhere, new Object[]{elder.getCardId()});
		if(qrMealCard.getTotalRecord()>0){
			mealCard = qrMealCard.getResultList().get(0);
			outFeeRecord.setMoneyMealCard(mealCard.getBalance());
			mealCard.setBalance(Float.valueOf(0));
			mealCard.setPreBalance(0F);//赠送余额清零
		}
		//结清赔偿金
		sqlWhere="elder_id=?1 AND comp_status=0";
		List<YrRoomAssetComp> roomAssetComps = new ArrayList<YrRoomAssetComp>();
		QueryResult<YrRoomAssetComp> qrRoomAssetComp = roomAssetCompService.find(YrRoomAssetComp.class, sqlWhere, new Object[]{elder.getElderId()});
		for(YrRoomAssetComp entity : qrRoomAssetComp.getResultList()){
			entity.setCompStatus(1);
			roomAssetComps.add(entity);
		}
		//结清所有欠费
		sqlWhere = "elder_id=?1 AND status=0";
		
//		List<YrElderArrearage> elderArrearages = new ArrayList<YrElderArrearage>();
//		QueryResult<YrElderArrearage> qrElderArrearage = elderArrearageService.find(YrElderArrearage.class,sqlWhere,new Object[]{elder.getElderId()});
//		for(YrElderArrearage entity : qrElderArrearage.getResultList()){
//			entity.setStatus(1);
//			elderArrearages.add(entity);
//		}
		
		sqlWhere = "be_hospital_id=?1 AND status=1";
		QueryResult<YrElderOutOrder> qr = elderOutOrderService.find(YrElderOutOrder.class, sqlWhere, new Object[]{beHospitalId});
		List<YrElderOutOrder> elderOutOrders = new ArrayList<YrElderOutOrder>();
		for(YrElderOutOrder elderOutOrder : qr.getResultList()){
			elderOutOrder.setStatus(2);//设置为失效状态
			elderOutOrder.setUpdateId("-1");
			elderOutOrder.setUpdateTime(new Date());
			elderOutOrders.add(elderOutOrder);
		}

		//获取票据号码
		sqlWhere = "staff_id=?1 AND paper_type=3";
		QueryResult<YrPaper> qrPaper = paperService.find(YrPaper.class, sqlWhere, new Object[]{loginedUser.getStaffId()});
		
		if(qrPaper.getResultList().isEmpty()){
			throwExp("暂无该类型的票据号，请先设置");
		}
		
		YrPaper paper = qrPaper.getResultList().get(0);
		YrPaperRecord paperRecord = costPaperRecord(paper, beHospitalId, loginedUser.getStaffId(), outFeeRecord.getTotalFee(),5);
				
		paperRecord.setRelationId(elderBeHospital.getBeHospitalId()+"-outHospital");
		paperRecord.setPledge(outFeeRecord.getPledge());
		paperRecord.setTotalFee(outFeeRecord.getTotalFee());
		paperRecord.setTotalPay(outFeeRecord.getTotalPay());
		paper.setUseNum(toNumberStr(paper.getUseNum()));	
		
		elderBeHospital.setBeStatus(2);//设置为出院状态
		FavoriteSet favoriteSet = new FavoriteSet();
		favoriteSet.putFavorite("beHospitalPledges", beHospitalPledges);
//		favoriteSet.putFavorite("leasePledges", leasePledges);
		favoriteSet.putFavorite("elderWallet", elderWallet);
		favoriteSet.putFavorite("mealCard", mealCard);
		favoriteSet.putFavorite("roomAssetComps", roomAssetComps);
//		favoriteSet.putFavorite("elderArrearages", elderArrearages);
		favoriteSet.putFavorite("elderBeHospital", elderBeHospital);
//		favoriteSet.putFavorite("bed",bed);
		favoriteSet.putFavorite("elderOutOrders",elderOutOrders);
		favoriteSet.putFavorite("outFeeRecord", outFeeRecord);
		favoriteSet.putFavorite("paperRecord", paperRecord);
		favoriteSet.putFavorite("paper", paper);
		
		elderService.costSettlement(favoriteSet);
		return result;
	}
	
	/**
	 * 抛出异常
	 * @param info
	 * @throws MyException
	 */
	public void throwExp(String info) throws MyException{
		MyException ex = new MyException(new MyMessage(info));
		ex.messages.addError(ex);
		throw ex;
	}

	@Override
	public Object toForm(Object e) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object toEntity(Object f) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}
}
